package Reflect;

import java.lang.reflect.Method;
import java.sql.Driver;
import java.util.Scanner;

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {

        /*
        在JVM进行类加载的时候会讲jvm中已经被加载的类和Class类对象进行绑定
        运行时间jvm类加载是要早于累的实例化的
        */
        /**
         * 反射存在的意义最终的要是一些类，一些函数我们并不想在设计初始就把他们写死，我们想在运行阶段根据需要进行
         * 不同类的实例化。可扩展性很强，但是相对的消耗了一些资源，运行速度效率会比较低
         */
//        Class<String> cls1 = String.class;
//        Class<Driver> driverClass = Driver.class;
//        Class<?> aClass = Class.forName("java.lang.String");
//        System.out.println("aClass: "+aClass);
//        System.out.println("cls1: "+cls1);
//        System.out.println("driverClass: "+driverClass);
//        String name = cls1.getName();
//        String simpleName = cls1.getSimpleName();
//        System.out.println("simpleName: "+simpleName);
//        System.out.println("NameAll: "+name);
        System.out.println("==================================传奇老师代码如下=================================================");

        /*
            反射的第一步，获取要操作的类的类对象
            java.lang.Class 类对象
            它的每一个实例用于表示一个被JVM加载的类。
            意味着JVM每加载一个类(读取对应类的.class文件)的同时会实例化
            一个Class实例与之绑定，并在该Class实例上记录加载的类的一切信息
            因此每个被加载的类都有且只有一个Class的实例与之对应，通过这个
            类对象就可以了解其表示的类的所有信息

            获取一个类对象的方式
            1.通过类名.class
               Class cls = String.class;//获取String的类对象
               Class cls2 = int.class;//基本类型也可以获取类对象

            2.Class.forName(String className)
              Class cls3 = Class.forName("java.lang.String");

            3.类加载器ClassLoader
            4.对象.getClass()
         */

        //获取String的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;

        //通过指定类的完全限定名获取一个类的类对象
//        Class cls = Class.forName("java.lang.String");
//        Class cls = Class.forName("java.util.ArrayList");
        /*
            java.lang.String
            java.util.ArrayList
            java.util.HashMap
            java.io.FileInputStream
         */
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入一个类的完全限定名：");
        String string = scan.nextLine();
        //获取Class类对象的第一种方法(通过类的完全限定名)
        Class<?> aClass = Class.forName(string);
        System.out.println("aClass: "+aClass);
        //获取Class类对象的第二种方法(直接通过类名调用.class)
        Class<String> stringClass = String.class;
        System.out.println(stringClass);

        //获取类的完全限定名
        String name = aClass.getName();
        System.out.println("类的完全限定名： "+name);
        //获取类的名字
        String simpleName = aClass.getSimpleName();
        String simpleName1 = simpleName;
        System.out.println("获取类名"+simpleName1);


        //获取包路径
        Package aPackage = Package.getPackage("java.lang");
        System.out.println("aPackage: "+aPackage);

        //获取类中的方法
        Class<Double> doubleClass = Double.class;
        Method[] methods = doubleClass.getMethods();
        int num = methods.length;
        System.out.println("方法总数num: "+num);
        for (Method method : methods) {
            System.out.println(method);
        }



    }
}
